#include <cppunit/config/SourcePrefix.h>
#include "TestProcTable.h"
#include <string>
#include <algorithm>
using namespace std;

void TestProcTable::setUp() {
	table = ProcTable();
}

void TestProcTable::tearDown() {
}

CPPUNIT_TEST_SUITE_REGISTRATION( TestProcTable );

void TestProcTable::testAddProc(){
	int index;

	index = table.addProc(string("x"));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("procedure \"x\" added to index 0", 0, index);

	index = table.addProc(string("y"));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("procedure \"y\" added to index 1", 1, index);
	
	index = table.addProc(string("z"));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("procedure \"z\" added to index 2", 2, index);
	
	index = table.addProc(string("x"));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("reinsert \"x\"", 0, index);
}

void TestProcTable::testAddProcNodeID(){
	int indexX = table.addProc(string("x"));
	
	CPPUNIT_ASSERT_EQUAL_MESSAGE("add nodeID 1 to procedure \"x\"", true, table.addProcNodeID(indexX,1));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("re-add nodeID 1 to procedure \"x\"", false, table.addProcNodeID(indexX,1));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("add nodeID 2 to non-existent procedure", false, table.addProcNodeID(1000000,1));		
}

void TestProcTable::testGetIndex(){
	int indexX = table.addProc(string("x"));
	int indexY = table.addProc(string("y"));
	int indexZ = table.addProc(string("z"));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for index of \"x\"", indexX, table.getIndex(string("x")));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for index of \"y\"", indexY, table.getIndex(string("y")));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for index of \"z\"", indexZ, table.getIndex(string("z")));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for unknown procedure", -1, table.getIndex(string("unknown")));
}

void TestProcTable::testGetProcName(){
	int indexX = table.addProc(string("x"));
	int indexY = table.addProc(string("y"));
	int indexZ = table.addProc(string("z"));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for \"x\"", string("x"), table.getProcName(indexX));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for \"y\"", string("y"), table.getProcName(indexY));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for \"z\"", string("z"), table.getProcName(indexZ));
	CPPUNIT_ASSERT_EQUAL_MESSAGE("search for unknown variable", string(""), table.getProcName(1000000));
}

void TestProcTable::testGetNodeIDs(){
	int indexX = 0;
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of unknown procedure", table.getNodeIDs(indexX).empty());
	indexX = table.addProc(string("x"));
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"", 
							table.getNodeIDs(indexX).size() == 0);
	CPPUNIT_ASSERT_EQUAL_MESSAGE("successfully add node id 1 to \"x\"", true, table.addProcNodeID(indexX,1));
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"",
							table.getNodeIDs(indexX).size() == 1
							&& find(table.getNodeIDs(indexX).begin(), table.getNodeIDs(indexX).end(), 1) != table.getNodeIDs(indexX).end()
						  );
	CPPUNIT_ASSERT_EQUAL_MESSAGE("successfully add node id 2 to \"x\"", true, table.addProcNodeID(indexX,2));
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"", 
							table.getNodeIDs(indexX).size() == 2
							&& find(table.getNodeIDs(indexX).begin(), table.getNodeIDs(indexX).end(), 1) != table.getNodeIDs(indexX).end()
							&& find(table.getNodeIDs(indexX).begin(), table.getNodeIDs(indexX).end(), 2) != table.getNodeIDs(indexX).end()
						  );
	CPPUNIT_ASSERT_EQUAL_MESSAGE("fail to re-add node id 1 to \"x\"", false, table.addProcNodeID(indexX,1));
	CPPUNIT_ASSERT_MESSAGE("get nodeIDs of \"x\"", 
							table.getNodeIDs(indexX).size() == 2
							&& find(table.getNodeIDs(indexX).begin(), table.getNodeIDs(indexX).end(), 1) != table.getNodeIDs(indexX).end()
							&& find(table.getNodeIDs(indexX).begin(), table.getNodeIDs(indexX).end(), 2) != table.getNodeIDs(indexX).end()
						  );
}
